home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / TEXTEDIT.SWG / 0012_7K Text Editor (GHOSTED).pas < prev    next >
Pascal/Delphi Source File  |  1994-04-06  |  11KB  |  677 lines

  1. {
  2. SEAN PALMER
  3.  
  4. > Can anyone (please, it's important) , post here an example of a source
  5. > code that will show a Text File , and let me scroll it (Up , Down ) ?
  6. > Also I need an example of a simple editor.
  7.  
  8. Try this For an example. Turbo Pascal 6.0+ source.
  9. Compiles to a 7K Text editor. Neat?
  10. }
  11.  
  12. {$A-,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X+}
  13. {$M $C00,0,0}
  14.  
  15. Program ghostEd; {Ghost Editor v0.4 (C) 1993 Sean L. Palmer}
  16.  
  17. Const
  18.   version  = '0.4';
  19.   maxF     = $3FFF;     {only handles small Files!}
  20.   txtColor = $B;
  21.   vSeg     : Word = $B800;
  22.  
  23. Var
  24.   nLines   : Byte;
  25.   halfPage : Byte;
  26.   txt      : Array [0..maxF] of Char;
  27.   crs,
  28.   endF,
  29.   pgBase,
  30.   lnBase   : Integer;
  31.   x, y     : Word;
  32.   update   : Boolean;
  33.   theFile  : File;
  34.   ticks    : Word Absolute $40 : $6C;   {ticks happen 18.2 times/second}
  35.  
  36. Procedure syncTick;
  37. Var
  38.   i : Word;
  39. begin
  40.   i := ticks;
  41.   Repeat Until i <> ticks;
  42. end;
  43.  
  44. Function readKey : Char; Assembler;
  45. Asm
  46.   mov ah, $07
  47.   int $21
  48. end;
  49.  
  50. Function keyPressed : Boolean; Assembler;
  51. Asm
  52.   mov ah, $B
  53.   int $21
  54.   and al, $FE
  55. end;
  56.  
  57. Procedure moveScrUp(s, d, n : Word); Assembler;
  58. Asm
  59.   mov  cx, n
  60.   push ds
  61.   mov  ax, vSeg
  62.   mov  es, ax
  63.   mov  ds, ax
  64.         mov  si, s
  65.   shl  si, 1
  66.   mov  di, d
  67.   shl  di, 1
  68.   cld
  69.   repz movsw {attr too!}
  70.   pop  ds
  71.  @X:
  72. end;
  73.  
  74. Procedure moveScrDn(s, d, n : Word); Assembler;
  75. Asm
  76.   mov  cx, n
  77.   push ds
  78.   mov  ax, vSeg
  79.   mov  es, ax
  80.   mov  ds, ax
  81.   mov  si, s
  82.   add  si, cx
  83.   shl  si, 1
  84.   mov  di, d
  85.   add  di, cx
  86.   shl  di, 1
  87.   std
  88.   repz movsw {attr too!}
  89.   pop  ds
  90.  @X:
  91. end;
  92.  
  93. Procedure moveScr(Var s; d, n : Word); Assembler;
  94. Asm
  95.   mov  cx, n
  96.   jcxz @X
  97.   push ds
  98.   mov  ax, vSeg
  99.   mov  es, ax
  100.   mov  di, d
  101.   shl  di, 1
  102.   lds  si, s
  103.   cld
  104.  @L:
  105.   movsb
  106.   inc  di
  107.   loop @L
  108.   pop  ds
  109.  @X:
  110. end;
  111.  
  112. Procedure fillScr(d, n : Word; c : Char); Assembler;
  113. Asm
  114.   mov  cx, n
  115.   jcxz @X
  116.   mov  ax, vSeg
  117.   mov  es, ax
  118.   mov  di, d
  119.   shl  di, 1
  120.   mov  al, c
  121.   cld
  122.  @L:
  123.   stosb
  124.   inc  di
  125.   loop @L
  126.  @X:
  127. end;
  128.  
  129. Procedure fillAttr(d, n : Word; c : Byte); Assembler;
  130. Asm
  131.   mov  cx, n
  132.   jcxz @X
  133.   mov  ax, vSeg
  134.   mov  es, ax
  135.   mov  di, d
  136.   shl  di, 1
  137.   mov  al, c
  138.   cld
  139.  @L:
  140.   inc  di
  141.   stosb
  142.   loop @L
  143.  @X:
  144. end;
  145.  
  146. Procedure cls;
  147. begin
  148.   fillAttr(80, pred(nLines) * 80, txtColor);
  149.   fillScr(80, pred(nLines) * 80, ' ');
  150. end;
  151.  
  152. Procedure scrollUp;
  153. begin
  154.   moveScrUp(320, 160, pred(nLines) * 160);
  155.   fillScr(pred(nLines) * 160, 80, ' ');
  156. end;
  157.  
  158. Procedure scrollDn;
  159. begin
  160.   moveScrDn(160, 320, pred(nLines) * 320);
  161.   fillScr(160, 80, ' ');
  162. end;
  163.  
  164. {put cursor after preceding CR or at 0}
  165. Function scanCrUp(i : Integer) : Integer; Assembler;
  166. Asm
  167.   mov   di, i
  168.   mov   cx, di
  169.   add   di, offset txt
  170.   mov   ax, ds
  171.   mov   es, ax
  172.   std;
  173.   mov   al, $D
  174.   dec   di
  175.   repnz scasb
  176.   jnz   @S
  177.   inc   di
  178.  @S:
  179.   inc   di
  180.   sub   di, offset txt
  181.   mov   ax, di
  182. end;
  183.  
  184. {put cursor on next CR or endF}
  185. Function scanCrDn(i:Integer):Integer;Assembler;Asm
  186.   mov   di, i
  187.   mov   cx, endF
  188.   sub   cx, di
  189.   inc   cx
  190.   add   di, offset txt
  191.   mov   ax, ds
  192.   mov   es, ax
  193.   cld
  194.   mov   al, $D
  195.   repnz scasb
  196.   dec   di
  197.   sub   di, offset txt
  198.   mov   ax, di
  199. end;
  200.  
  201. Procedure findxy;
  202. begin
  203.   lnBase := scanCrUp(crs);
  204.   x      := crs - lnBase;
  205.   y      := 1;
  206.   pgBase := lnBase;
  207.   While (pgBase > 0) and (y < halfPage) do
  208.   begin
  209.     pgBase := scanCrUp(pred(pgBase));
  210.     inc(y);
  211.   end;
  212. end;
  213.  
  214. Procedure display;
  215. Var
  216.   i, j, k, oldY : Integer;
  217. begin
  218.   findXY;
  219.   if update then
  220.   begin
  221.     update := False;
  222.     j := pgBase;
  223.     i := 1;
  224.     While (j <= endf) and (i < pred(nLines)) do
  225.     begin
  226.       k := scanCrDn(j);
  227.       moveScr(txt[j], i * 80, k - j);
  228.       fillScr(i * 80 + k - j, 80 - k + j, ' ');
  229.       fillAttr(i * 80, 80, txtColor);
  230.       j := succ(k);
  231.       inc(i);
  232.     end;
  233.     if i < pred(nLines) then
  234.     begin
  235.       fillScr(i * 80, 80 * pred(nLines - i), 'X');
  236.       fillAttr(i * 80, 80 * pred(nLines - i), 1);
  237.     end;
  238.   end
  239.   else
  240.   begin
  241.     i := scanCrDn(lnBase) - lnBase;
  242.     moveScr(txt[lnBase], y * 80, i);
  243.     fillScr(y * 80 + i, 80 - i, ' ');
  244.   end;
  245. end;
  246.  
  247. Procedure title;
  248. Const
  249.   menuStr : String = 'Ghost Editor v' + version + '-(C) Sean Palmer 1993';
  250. begin
  251.   fillAttr(0, 80, $70);
  252.   fillScr(0, 80, ' ');
  253.   MoveScr(MenuStr[1], 1, length(MenuStr));
  254. end;
  255.  
  256. Procedure error(s : String);
  257. begin
  258.   fillattr(0, 80, $CE);
  259.   fillScr(0, 80, ' ');
  260.   moveScr(s[1], 1, length(s));
  261.   Write(^G);
  262.   ReadKey;
  263.   title;
  264. end;
  265.  
  266. Procedure tooBigErr;
  267. begin
  268.   error('File too big');
  269. end;
  270.  
  271. Procedure insChar(c : Char); forward;
  272. Procedure delChar; forward;
  273. Procedure backChar; forward;
  274.  
  275. Procedure trimLine;
  276. Var
  277.   i, t, b : Integer;
  278. begin
  279.   i   := crs;
  280.   b   := scanCrDn(crs);
  281.   t   := scanCrUp(crs);
  282.   crs := b;
  283.   While txt[crs] = ' ' do
  284.   begin
  285.     delChar;
  286.     if i > crs then
  287.       dec(i);
  288.     if crs > 0 then
  289.       dec(crs);
  290.   end;
  291.   crs := i;
  292. end;
  293.  
  294. Procedure checkWrap(c : Integer);
  295. Var
  296.   i, t, b : Integer;
  297. begin
  298.   b := scanCrDn(c);
  299.   t := scanCrUp(c);
  300.   i := b;
  301.   if i - t >= 79 then
  302.   begin
  303.     i := t + 79;
  304.     Repeat
  305.       dec(i);
  306.     Until (txt[i] = ' ') or (i = t);
  307.     if i = t then
  308.       backChar   {just disallow lines that long With no spaces}
  309.     else
  310.     begin
  311.       txt[i] := ^M;  {change sp into cr, to wrap}
  312.       update := True;
  313.       if (b < endF) and (txt[b] = ^M) and (txt[succ(b)] <> ^M) then
  314.       begin
  315.         txt[b] := ' '; {change cr into sp, to append wrapped part to next
  316. line}         checkWrap(b);  {recursively check next line since it got stuff
  317. added}       end;
  318.     end;
  319.   end;
  320. end;
  321.  
  322. Procedure changeLines;
  323. begin
  324.   trimLine;
  325.   update := True;  {signal to display to redraw}
  326. end;
  327.  
  328. Procedure insChar(c : Char);
  329. begin
  330.   if endf = maxF then
  331.   begin
  332.     tooBigErr;
  333.     exit;
  334.   end;
  335.   move(txt[crs], txt[succ(crs)], endf - crs);
  336.   txt[crs] := c;
  337.   inc(crs);
  338.   inc(endf);
  339.   if c = ^M then
  340.     changeLines;
  341.   checkWrap(crs);
  342. end;
  343.  
  344. Procedure delChar;
  345. begin
  346.   if crs = endf then
  347.     Exit;
  348.   if txt[crs] = ^M then
  349.     changeLines;
  350.   move(txt[succ(crs)], txt[crs], endf - crs);
  351.   dec(endf);
  352.   checkWrap(crs);
  353. end;
  354.  
  355. Procedure addLF;
  356. Var
  357.   i : Integer;
  358. begin
  359.   For crs := endF downto 1 do
  360.   if txt[pred(crs)] = ^M then
  361.   begin
  362.     insChar(^J);
  363.     dec(crs);
  364.   end;
  365. end;
  366.  
  367. Procedure stripLF;
  368. Var
  369.   i : Integer;
  370. begin
  371.   For crs := endF downto 0 do
  372.   if txt[crs] = ^J then
  373.     delChar;
  374. end;
  375.  
  376. Procedure WriteErr;
  377. begin
  378.   error('Write Error');
  379. end;
  380.  
  381. Procedure saveFile;
  382. begin
  383.   addLF;
  384.   reWrite(theFile, 1);
  385.   if ioresult <> 0 then
  386.     WriteErr
  387.   else
  388.   begin
  389.     blockWrite(theFile, txt, endf);
  390.     if ioresult <> 0 then
  391.       WriteErr;
  392.     close(theFile);
  393.   end;
  394. end;
  395.  
  396. Procedure newFile;
  397. begin
  398.   crs    := 0;
  399.   endF   := 0;
  400.   update := True;
  401. end;
  402.  
  403. Procedure readErr;
  404. begin
  405.   error('Read Error');
  406. end;
  407.  
  408. Procedure loadFile;
  409. Var
  410.   i, n : Integer;
  411. begin
  412.   reset(theFile, 1);
  413.   if ioresult <> 0 then
  414.     newFile
  415.   else
  416.   begin
  417.     n := Filesize(theFile);
  418.     if n > maxF then
  419.     begin
  420.       tooBigErr;
  421.       n := maxF;
  422.     end;
  423.     blockread(theFile, txt, n, i);
  424.     if i < n then
  425.       readErr;
  426.     close(theFile);
  427.     crs    := 0;
  428.     endf   := i;
  429.     update := True;
  430.     stripLF;
  431.   end;
  432. end;
  433.  
  434. Procedure signOff;
  435. Var
  436.   f    : File;
  437.   i, n : Integer;
  438. begin
  439.   assign(f, 'signoff.txt');
  440.   reset(f, 1);
  441.   if ioresult <> 0 then
  442.     error('No SIGNOFF.TXT defined')  {no macro defined}
  443.   else
  444.   begin
  445.     n := Filesize(f);
  446.     blockread(f, txt[endF], n, i);
  447.     if i < n then
  448.       readErr;
  449.     close(f);
  450.     inc(endf, i);
  451.     update := True;
  452.     i := crs;
  453.     stripLF;
  454.     crs := i; {stripLF messes With crs}
  455.   end;
  456. end;
  457.  
  458. Procedure goLf;
  459. begin
  460.   if crs > 0 then
  461.     dec(crs);
  462.   if txt[crs] = ^M then
  463.     changeLines;
  464. end;
  465.  
  466. Procedure goRt;
  467. begin
  468.   if txt[crs] = ^M then
  469.     changeLines;
  470.   if crs < endf then
  471.     inc(crs);
  472. end;
  473.  
  474. Procedure goCtrlLf;
  475. Var
  476.   c : Char;
  477. begin
  478.   Repeat
  479.     goLf;
  480.     c := txt[crs];
  481.   Until (c <= ' ') or (crs = 0);
  482. end;
  483.  
  484. Procedure goCtrlRt;
  485. Var
  486.   c : Char;
  487. begin
  488.   Repeat
  489.     goRt;
  490.     c := txt[crs];
  491.   Until (c <= ' ') or (crs >= endF);
  492. end;
  493.  
  494. Procedure goUp;
  495. Var
  496.   i : Integer;
  497. begin
  498.   if lnBase > 0 then
  499.   begin
  500.     changeLines;
  501.     lnBase := scanCrUp(pred(lnBase));
  502.     crs := lnBase;
  503.     i := scanCrDn(crs) - crs;
  504.     if i >= x then
  505.       inc(crs, x)
  506.     else
  507.       inc(crs,i);
  508.   end;
  509. end;
  510.  
  511. Procedure goDn;
  512. Var
  513.   i : Integer;
  514. begin
  515.   changeLines;
  516.   crs := scanCrDn(crs);
  517.   if crs >= endF then
  518.     Exit;
  519.   inc(crs);
  520.   lnBase := crs;
  521.   i := scanCrDn(crs) - crs;
  522.   if i >= x then
  523.     inc(crs, x)
  524.   else
  525.     inc(crs, i);
  526. end;
  527.  
  528. Procedure goPgUp;
  529. Var
  530.   i : Byte;
  531. begin
  532.   For i := halfPage downto 0 do
  533.     goUp;
  534. end;
  535.  
  536. Procedure goPgDn;
  537. Var
  538.   i : Byte;
  539. begin
  540.   For i := halfPage downto 0 do
  541.     goDn;
  542. end;
  543.  
  544. Procedure goHome;
  545. begin
  546.   crs := scanCrUp(crs);
  547. end;
  548.  
  549. Procedure goend;
  550. begin
  551.   crs := scanCrDn(crs);
  552. end;
  553.  
  554. Procedure backChar;
  555. begin
  556.   if (crs > 0) then
  557.   begin
  558.     goLf;
  559.     delChar;
  560.   end;
  561. end;
  562.  
  563. Procedure deleteLine;
  564. Var
  565.   i : Integer;
  566. begin
  567.   i := scanCrDn(crs);
  568.   crs := scanCrUp(crs);
  569.   if i < endF then
  570.   begin
  571.     move(txt[succ(i)], txt[crs], endf - i);
  572.     dec(endF);
  573.   end;
  574.   dec(endf, i - crs);
  575.   changeLines;
  576. end;
  577.  
  578. Procedure flipCursor;
  579. Var
  580.   j, k, l : Word;
  581. begin
  582.   j := succ((y * 80 + x) shl 1);
  583.   l := mem[vSeg : j];   {save attr under cursor}
  584.   mem[vSeg : j] := $7B;
  585.   if not KeyPressed then
  586.     syncTick;
  587.   mem[vSeg : j] := l;
  588.   if not KeyPressed then
  589.     syncTick;
  590. end;
  591.  
  592. Procedure edit;
  593. Var
  594.   c : Char;
  595. begin
  596.   Repeat
  597.     display;
  598.     Repeat
  599.       flipcursor;
  600.     Until KeyPressed;
  601.  
  602.     c := ReadKey;
  603.     if c = #0 then
  604.       Case ReadKey of
  605.         #59  : signOff;
  606.         #75  : goLf;
  607.         #77  : goRt;
  608.         #115 : goCtrlLf;
  609.         #116 : goCtrlRt;
  610.         #72  : goUp;
  611.         #80  : goDn;
  612.         #83  : delChar;
  613.         #73  : goPgUp;
  614.         #81  : goPgDn;
  615.         #71  : goHome;
  616.         #79  : goend;
  617.       end
  618.     else
  619.       Case c of
  620.         ^[ : saveFile;
  621.         ^H : backChar;
  622.         ^C : {abortFile};
  623.         ^Y : deleteLine;
  624.      else
  625.        insChar(c);
  626.      end;
  627.   Until (c = ^[) or (c = ^C);
  628. end;
  629.  
  630. Function getRows : Byte; Assembler;
  631. Asm
  632.   mov  ax, $1130
  633.   xor  dx, dx
  634.   int  $10
  635.   or   dx, dx
  636.   jnz  @S
  637.   mov  dx, 24
  638.  @S: {cga/mda don't have this fn}
  639.   inc  dx
  640.   mov  al, dl
  641. end;
  642.  
  643. Var
  644.   oldMode : Byte;
  645. begin
  646.   Asm
  647.     mov ah, $F
  648.     int $10
  649.     mov oldMode, al
  650.   end;  {save old Gr mode}
  651.  
  652.   if oldMode = 7 then
  653.     vSeg := $B000;  {check For Mono}
  654.  
  655.   nLines := getRows;
  656.   halfPage := pred(nLines shr 1);
  657.   cls;
  658.   title;
  659.  
  660.   if paramCount = 0 then
  661.     error('Need Filename as parameter')
  662.   else
  663.   begin
  664.     Asm
  665.       mov bh, 0
  666.       mov dl, 0
  667.       mov dh, nLines
  668.       mov ah, 2
  669.       int $10
  670.     end; {put cursor of}
  671.  
  672.     assign(theFile, paramStr(1));
  673.     loadFile;
  674.     edit;
  675.   end;
  676. end.
  677.